﻿using Base.Api.Models;
using Common.AspNetCore;
using Consul;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Base.Api.Service
{
    public class ServiceRegisterService : CommonService
    {
        public ServiceRegisterService(IServiceProvider provider) : base(provider)
        {
        }

        public async Task<string> DeletePublishServiceAsync(ServiceRegisterParamModel model)
        {
            if (string.IsNullOrEmpty(model.ServiceCode) || string.IsNullOrEmpty(model.ServiceUrl))
            {
                return null;
            }

            ////默认暂停30秒
            if (model.DelaySecond == 0)
            {
                model.DelaySecond = 30;
            }

            string ret = string.Empty;
            using (var consulClient = new ConsulClient(options =>
            {
                options.Address = new Uri(model.ServiceUrl);
            }))
            {
                var options = new QueryOptions
                {
                    WaitTime = TimeSpan.FromSeconds(1)
                };

                var result = await consulClient.Health.Service(model.ServiceCode, null, true, options);
                if (result != null && result.Response != null)
                {
                    foreach (var t in result.Response)
                    {
                        if (t.Service.Address == model.Ip)
                        {
                            if (consulClient.Agent != null)
                            {
                                await consulClient.Agent.ServiceDeregister(t.Service.ID);
                                ret = "1";
                            }
                        }
                    }
                }
            }

            if (ret == "1")
            {
                await Task.Delay(TimeSpan.FromSeconds(model.DelaySecond));
            }

            return ret;
        }

        public async Task<int> CheckServiceHealthAsync(ServiceRegisterParamModel model)
        {
            if (string.IsNullOrEmpty(model.ServiceCode) || string.IsNullOrEmpty(model.ServiceUrl))
            {
                return -1;
            }

            // 默认60秒
            if (model.DelaySecond == 0)
            {
                model.DelaySecond = 60;
            }

            // 等待5s让docker启动
            await Task.Delay(5 * 1000);

            int ret = 0;

            using (var consulClient = new ConsulClient(options =>
            {
                options.Address = new Uri(model.ServiceUrl);
            }))
            {
                var options = new QueryOptions
                {
                    WaitTime = TimeSpan.FromSeconds(1)
                };

                var elapsed = 0m;

                while (elapsed < model.DelaySecond)
                {
                    var result = await consulClient.Health.Service(model.ServiceCode, null, true, options);
                    if (result != null && result.Response != null)
                    {
                        foreach (var t in result.Response)
                        {
                            if (t.Service.Address != model.Ip)
                            {
                                continue;
                            }

                            if (t.Checks != null && t.Checks.All(x => x.Status == HealthStatus.Passing))
                            {
                                ret++;
                                break;
                            }
                        }
                    }

                    if (ret >= 1)
                    {
                        await Task.Delay(3 * 1000);
                        break;
                    }

                    elapsed += 3;
                    await Task.Delay(3 * 1000);
                }

                return ret;
            }
        }
    }
}
